home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / ruby / 1.8 / thwait.rb < prev    next >
Text File  |  2007-02-12  |  4KB  |  170 lines

  1. #
  2. #   thwait.rb - thread synchronization class
  3. #       $Release Version: 0.9 $
  4. #       $Revision: 1.3 $
  5. #       $Date: 1998/06/26 03:19:34 $
  6. #       by Keiju ISHITSUKA(Nihpon Rational Software Co.,Ltd.)
  7. #
  8. # --
  9. #  feature:
  10. #  provides synchronization for multiple threads.
  11. #
  12. #  class methods:
  13. #  * ThreadsWait.all_waits(thread1,...)
  14. #    waits until all of specified threads are terminated.
  15. #    if a block is supplied for the method, evaluates it for
  16. #    each thread termination.
  17. #  * th = ThreadsWait.new(thread1,...)
  18. #    creates synchronization object, specifying thread(s) to wait.
  19. #  
  20. #  methods:
  21. #  * th.threads
  22. #    list threads to be synchronized
  23. #  * th.empty?
  24. #    is there any thread to be synchronized.
  25. #  * th.finished?
  26. #    is there already terminated thread.
  27. #  * th.join(thread1,...) 
  28. #    wait for specified thread(s).
  29. #  * th.join_nowait(threa1,...)
  30. #    specifies thread(s) to wait.  non-blocking.
  31. #  * th.next_wait
  32. #    waits until any of specified threads is terminated.
  33. #  * th.all_waits
  34. #    waits until all of specified threads are terminated.
  35. #    if a block is supplied for the method, evaluates it for
  36. #    each thread termination.
  37. #
  38.  
  39. require "thread.rb"
  40. require "e2mmap.rb"
  41.  
  42. #
  43. # This class watches for termination of multiple threads.  Basic functionality
  44. # (wait until specified threads have terminated) can be accessed through the
  45. # class method ThreadsWait::all_waits.  Finer control can be gained using
  46. # instance methods.
  47. #
  48. # Example:
  49. #
  50. #   ThreadsWait.all_wait(thr1, thr2, ...) do |t|
  51. #     STDERR.puts "Thread #{t} has terminated."
  52. #   end
  53. #
  54. class ThreadsWait
  55.   RCS_ID='-$Id: thwait.rb,v 1.3 1998/06/26 03:19:34 keiju Exp keiju $-'
  56.   
  57.   Exception2MessageMapper.extend_to(binding)
  58.   def_exception("ErrNoWaitingThread", "No threads for waiting.")
  59.   def_exception("ErrNoFinishedThread", "No finished threads.")
  60.   
  61.   #
  62.   # Waits until all specified threads have terminated.  If a block is provided,
  63.   # it is executed for each thread termination.
  64.   #
  65.   def ThreadsWait.all_waits(*threads) # :yield: thread
  66.     tw = ThreadsWait.new(*threads)
  67.     if block_given?
  68.       tw.all_waits do |th|
  69.     yield th
  70.       end
  71.     else
  72.       tw.all_waits
  73.     end
  74.   end
  75.   
  76.   #
  77.   # Creates a ThreadsWait object, specifying the threads to wait on.
  78.   # Non-blocking.
  79.   #
  80.   def initialize(*threads)
  81.     @threads = []
  82.     @wait_queue = Queue.new
  83.     join_nowait(*threads) unless threads.empty?
  84.   end
  85.   
  86.   # Returns the array of threads in the wait queue.
  87.   attr :threads
  88.   
  89.   #
  90.   # Returns +true+ if there are no threads to be synchronized.
  91.   #
  92.   def empty?
  93.     @threads.empty?
  94.   end
  95.   
  96.   #
  97.   # Returns +true+ if any thread has terminated.
  98.   #
  99.   def finished?
  100.     !@wait_queue.empty?
  101.   end
  102.   
  103.   #
  104.   # Waits for specified threads to terminate.
  105.   #
  106.   def join(*threads)
  107.     join_nowait(*threads)
  108.     next_wait
  109.   end
  110.   
  111.   #
  112.   # Specifies the threads that this object will wait for, but does not actually
  113.   # wait.
  114.   #
  115.   def join_nowait(*threads)
  116.     threads.flatten!
  117.     @threads.concat threads
  118.     for th in threads
  119.       Thread.start(th) do |t|
  120.     begin
  121.       t.join
  122.     ensure
  123.       @wait_queue.push t
  124.     end
  125.       end
  126.     end
  127.   end
  128.   
  129.   #
  130.   # Waits until any of the specified threads has terminated, and returns the one
  131.   # that does.
  132.   #
  133.   # If there is no thread to wait, raises +ErrNoWaitingThread+.  If +nonblock+
  134.   # is true, and there is no terminated thread, raises +ErrNoFinishedThread+.
  135.   #
  136.   def next_wait(nonblock = nil)
  137.     ThreadsWait.fail ErrNoWaitingThread if @threads.empty?
  138.     begin
  139.       @threads.delete(th = @wait_queue.pop(nonblock))
  140.       th
  141.     rescue ThreadError
  142.       ThreadsWait.fail ErrNoFinishedThread
  143.     end
  144.   end
  145.   
  146.   #
  147.   # Waits until all of the specified threads are terminated.  If a block is
  148.   # supplied for the method, it is executed for each thread termination.
  149.   #
  150.   # Raises exceptions in the same manner as +next_wait+.
  151.   #
  152.   def all_waits
  153.     until @threads.empty?
  154.       th = next_wait
  155.       yield th if block_given?
  156.     end
  157.   end
  158. end
  159.  
  160. ThWait = ThreadsWait
  161.  
  162.  
  163. # Documentation comments:
  164. #  - Source of documentation is evenly split between Nutshell, existing
  165. #    comments, and my own rephrasing.
  166. #  - I'm not particularly confident that the comments are all exactly correct.
  167. #  - The history, etc., up the top appears in the RDoc output.  Perhaps it would
  168. #    be better to direct that not to appear, and put something else there
  169. #    instead.
  170.